#include <iostream>
#include <vector>
#include <string>



#include <QtCore/QCoreApplication>
#include <QTest>
#include <QtTest\Qttest>
#include <qobject.h>
#include <QxtLogger>
#include <QxtBasicFileLoggerEngine>
#include <QxtBasicSTDLoggerEngine>
#include <QDebug>

#include "Entry.h"
#include "Event.h"
#include "Task.h"
#include "FileManager.h"
#include "EntriesManager.h"
#include "Tokeniser.h"
#include "FileManagerStub.h"
#include "EntryStub.h"
#include "botlogic.h"
#include "lineedit.h"
#include "OutputManager.h"
#include "CommonEnum.h"
#include "CommonUtils.h"

using namespace std;
//@author A0094511L
class GUILineEditTest:public QObject {
	Q_OBJECT
	
private:
	
		LineEdit commandInput;

	private slots:
		void initTestCase() {
			// Called before all unit tests.

			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");
			QxtLoggerEngine *stdoutLogger = new QxtBasicSTDLoggerEngine();

			qxtLog->addLoggerEngine("file", fileLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);
		}

		
		void testEnteringInput(){

		
			//Boundary case, entering of empty string
			QTest::keyClicks(&commandInput, "");
			QCOMPARE(commandInput.toPlainText(), QString(""));

			//Normal case, entering of normal input
			QTest::keyClicks(&commandInput, "add something");
			QCOMPARE(commandInput.toPlainText(), QString("add something"));
		}

		//Test self-implemented signals in custom QTextEdit

		void testEnterKeyPressedSignal(){

			QSignalSpy spyEnterKey(&commandInput, SIGNAL(enterKeyPressed()));

			QTest::keyClick(&commandInput, Qt::Key_Enter);

			//Only 1 enter press detected, and signal should be emitted when enter key is pressed
			QCOMPARE(spyEnterKey.count() , 1);

		}
	
		void testUndoShortCutPressedSignal(){

			QSignalSpy spyEnterKey(&commandInput, SIGNAL(undoShortcutPressed()));

			QTest::keyPress(&commandInput, Qt::Key_Z, Qt::ControlModifier);

			//Only 1 enter press detected, and signal should be emitted when enter key is pressed
			QCOMPARE(spyEnterKey.count() , 1);

		}

		void testRedoShortCutPressedSignal(){

			QSignalSpy spyEnterKey(&commandInput, SIGNAL(redoShortcutPressed()));

			QTest::keyPress(&commandInput, Qt::Key_Y, Qt::ControlModifier);

			//Only 1 enter press detected, and signal should be emitted when enter key is pressed
			QCOMPARE(spyEnterKey.count() , 1);

		}

		void testdownKeyPressedSignal(){

			QSignalSpy spyEnterKey(&commandInput, SIGNAL(downKeyPressed()));

			QTest::keyClick(&commandInput, Qt::Key_Down);

			//Only 1 enter press detected, and signal should be emitted when enter key is pressed
			QCOMPARE(spyEnterKey.count() , 1);

		}

		void testUpKeyPressedSignal(){

			QSignalSpy spyEnterKey(&commandInput, SIGNAL(upKeyPressed()));

			QTest::keyClick(&commandInput, Qt::Key_Up);

			//Only 1 enter press detected, and signal should be emitted when enter key is pressed
			QCOMPARE(spyEnterKey.count() , 1);

		}
};

class OutputManagerTest:public QObject {
	Q_OBJECT
private:

	vector<vector<CommonEnum::ReturnString>> outputFromEntriesManager;
	
	CommonEnum::ReturnString firstLine;
	OutputManager *converter;

	private slots:
		void initTestCase() {
			// Called before all unit tests.

			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");
			QxtLoggerEngine *stdoutLogger = new QxtBasicSTDLoggerEngine();

			qxtLog->addLoggerEngine("file", fileLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);
		}

		void onlyOneTestCase(){

			CommonEnum::ReturnString firstLine;
			firstLine.entry.first = "Today";
			firstLine.entry.second = "13/10/1991";
			firstLine.format = CommonEnum::DISPLAY_FORMAT_DEFAULT;
			vector<CommonEnum::ReturnString> innerVect;
			innerVect.push_back(firstLine);
			vector<vector<CommonEnum::ReturnString>> combinedVect;
			combinedVect.push_back(innerVect);
			converter = new OutputManager(combinedVect);
			QString htmlConverted = converter->getFormattedString();

			QString expectedOutput = "<table width = \"100%\"><tr><td align = \"left\" width = \"60%\">"
									 "<span style=\" font-size:15pt; font-weight:600;\">Today</td></span>"
									 "<td align = \"right\"><span style=\" font-size:15pt; font-weight:600;\">"
									 "13/10/1991</td></span></tr></table><br>";
			
			QCOMPARE(htmlConverted, expectedOutput);
			
		}

		void twoSectionTestCase(){

			CommonEnum::ReturnString firstSectionFirstLine;
			firstSectionFirstLine.entry.first = "Today";
			firstSectionFirstLine.entry.second = "13/10/1991";
			firstSectionFirstLine.format = CommonEnum::DISPLAY_FORMAT_DEFAULT;
			vector<CommonEnum::ReturnString> firstSection;
			firstSection.push_back(firstSectionFirstLine);
			vector<vector<CommonEnum::ReturnString>> combinedVect;
			combinedVect.push_back(firstSection);

			CommonEnum::ReturnString secondSectionFirstLine;
			secondSectionFirstLine.entry.first = "Tommorow";
			secondSectionFirstLine.entry.second = "14/10/1991";
			secondSectionFirstLine.format = CommonEnum::DISPLAY_FORMAT_DEFAULT;
			vector<CommonEnum::ReturnString> secondSection;
			secondSection.push_back(secondSectionFirstLine);

			combinedVect.push_back(secondSection);

			converter = new OutputManager(combinedVect);
			QString htmlConverted = converter->getFormattedString();

			QString expectedOutput = "<table width = \"100%\"><tr><td align = \"left\" width = \"60%\"><span style=\" font-size:15pt; font-weight:600;\">Today</td></span><td align = \"right\">"
								     "<span style=\" font-size:15pt; font-weight:600;\">13/10/1991</td></span></tr></table><br><table width = \"100%\"><tr><td align = \"left\" width = \"60%\">"
									 "<span style=\" font-size:15pt; font-weight:600;\">Tommorow</td></span><td align = \"right\"><span style=\" font-size:15pt; font-weight:600;\">14/10/1991</td>"
									 "</span></tr></table><br>";

			QCOMPARE(htmlConverted, expectedOutput);
		
		}

		void allFourSectionTestCase(){
			
			CommonEnum::ReturnString firstSectionFirstLine;
			firstSectionFirstLine.entry.first = "Overdue";
			firstSectionFirstLine.format = CommonEnum::DISPLAY_FORMAT_OVERDUE;
			CommonEnum::ReturnString firstSectionSecondLine;
			firstSectionSecondLine.entry.first = "CS Homework";
			firstSectionSecondLine.entry.second = "by 13 Oct";
			firstSectionSecondLine.format = CommonEnum::DISPLAY_FORMAT_DEFAULT;
			vector<CommonEnum::ReturnString> firstSection;
			firstSection.push_back(firstSectionFirstLine);
			firstSection.push_back(firstSectionSecondLine);
			

			CommonEnum::ReturnString secondSectionFirstLine;
			secondSectionFirstLine.entry.first = "Today";
			secondSectionFirstLine.entry.second = "14/10/1991";
			secondSectionFirstLine.format = CommonEnum::DISPLAY_FORMAT_TODAY;
			vector<CommonEnum::ReturnString> secondSection;
			secondSection.push_back(secondSectionFirstLine);
			
			CommonEnum::ReturnString thirdSectionFirstLine;
			thirdSectionFirstLine.entry.first = "Tommorrow";
			thirdSectionFirstLine.entry.second = "14/10/1991";
			thirdSectionFirstLine.format = CommonEnum::DISPLAY_FORMAT_DEFAULT;
			vector<CommonEnum::ReturnString> thirdSection;
			thirdSection.push_back(thirdSectionFirstLine);
			
			CommonEnum::ReturnString fourthSectionFirstLine;
			fourthSectionFirstLine.entry.first = "Future";
			fourthSectionFirstLine.format = CommonEnum::DISPLAY_FORMAT_DEFAULT;
			vector<CommonEnum::ReturnString> fourthSection;
			fourthSection.push_back(fourthSectionFirstLine);
			
			vector<vector<CommonEnum::ReturnString>> combinedVect;
			combinedVect.push_back(firstSection);
			combinedVect.push_back(secondSection);
			combinedVect.push_back(thirdSection);
			combinedVect.push_back(fourthSection);

			converter = new OutputManager(combinedVect);
			QString htmlConverted = converter->getFormattedString();

			QString expectedOutput = "<table width = \"100%\"><tr><td align = \"left\" width = \"60%\"><span style=\" font-size:15pt; font-weight:600; color: red;\">"
									 "Overdue</td></span></tr></table><br><table width = \"100%\"><tr><td align = \"left\" width = \"60%\"><span style=\" font-size:10pt; font-weight:600;\">"
									 "CS Homework</td></span><td align = \"right\"><span style=\" font-size:8pt; color:grey;\">by 13 Oct</td></span></tr></table><br><a id = \"today\"><table width = \"100%\"><tr>"
									 "<td align = \"left\" width = \"60%\"><span style=\" font-size:15pt; font-weight:600; color: green;\">Today</td></span><td align = \"right\"><span style=\" font-size:15pt; font-weight:600; color: green;\">"
									 "14/10/1991</td></span></tr></table><br></a><table width = \"100%\"><tr><td align = \"left\" width = \"60%\"><span style=\" font-size:15pt; font-weight:600;\">Tommorrow</td></span><td align = \"right\">"
									 "<span style=\" font-size:15pt; font-weight:600;\">14/10/1991</td></span></tr></table><br><table width = \"100%\"><tr><td align = \"left\" width = \"60%\"><span style=\" font-size:15pt; font-weight:600;\">Future</td></span></tr></table><br>";

			
			QCOMPARE(htmlConverted, expectedOutput);
		}
};
//@author A0100939H
class TokeniserTest:public QObject {
	Q_OBJECT
private:
	private slots:
		void initTestCase() {
			// Called before all unit tests.

			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");
			QxtLoggerEngine *stdoutLogger = new QxtBasicSTDLoggerEngine();

			qxtLog->addLoggerEngine("file", fileLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);
		}
		void testExtractLineNum() {
			string textLine = "delete 5";
			Tokeniser* tokeniser = new Tokeniser(textLine);
			CommonEnum::COMMAND_TYPE command = tokeniser->getCommand();
			int lineNum = tokeniser->extractLineNum();

			QVERIFY(lineNum == 5);
		}
		void testGetCommand() {
			string textLine = "add water plants";
			Tokeniser* tokeniser = new Tokeniser(textLine);
			CommonEnum::COMMAND_TYPE command = tokeniser->getCommand();

			QVERIFY(command == CommonEnum::COMMAND_ADD);
		}
		void testExtractKey() {
			string textLine = "add go shopping";
			Tokeniser* tokeniser = new Tokeniser(textLine);
			CommonEnum::COMMAND_TYPE command = tokeniser->getCommand();
			string keywords = tokeniser->extractKey();

			QVERIFY(keywords == "go shopping");
		}
		void testFormatDate() {  //boundary testing for the accepted patition and equivalence partition
			string textLine1 = "displayd 31/12/14";
			Tokeniser* tokeniser1 = new Tokeniser(textLine1);
			CommonEnum::COMMAND_TYPE command = tokeniser1->getCommand();
			string key = tokeniser1->extractKey();
			QDate qdate = tokeniser1->formatDate(key);

			QString qstr = QString::fromStdString("31/12/14");
			QDate dateToCompare = QDate::fromString(qstr, "dd/M/yy");
			dateToCompare = dateToCompare.addYears(100);

			QVERIFY(qdate == dateToCompare);

			string textLine2 = "displayd 5/3";
			Tokeniser* tokeniser2 = new Tokeniser(textLine2);
			CommonEnum::COMMAND_TYPE command2 = tokeniser2->getCommand();
			string key2 = tokeniser2->extractKey();
			QDate qdate2 = tokeniser2->formatDate(key2);

			QString qstr2 = QString::fromStdString("5/3");
			QDate dateToCompare2 = QDate::fromString(qstr2, "d/M");
			int yearsToAdd = (QDate::currentDate().year())-dateToCompare2.year();
			dateToCompare2 = dateToCompare2.addYears(yearsToAdd);

			QVERIFY(qdate2 == dateToCompare2);
		}
		void testGetEntry() {
			string textLine = "add go shopping from 12/4 to 16/4";
			Tokeniser* tokeniser = new Tokeniser(textLine);
			CommonEnum::COMMAND_TYPE command = tokeniser->getCommand();
			Entry* newEntry = tokeniser->getEntry();
			QDate startDate = QDate::fromString(QString::fromStdString("12/4"), "dd/M");
			int yearsToAdd1 = (QDate::currentDate().year())-startDate.year();
			startDate = startDate.addYears(yearsToAdd1);

			QDate endDate = QDate::fromString(QString::fromStdString("16/4"), "dd/M");
			int yearsToAdd2 = (QDate::currentDate().year())-endDate.year();
			endDate = endDate.addYears(yearsToAdd2);


			QVERIFY(command == CommonEnum::COMMAND_ADD);
			QVERIFY(newEntry->getStartDate() == startDate);
			QVERIFY(newEntry->getEndDate() == endDate);

		}
		void testCheckFormat() {
			string textLine1 = "add go shopping from mon to fri";
			Tokeniser* tokeniser1 = new Tokeniser(textLine1);
			bool check1 = tokeniser1->checkFormat(textLine1);

			QVERIFY(check1 == true);

			string textLine2 = "add go shopping from mon";
			Tokeniser* tokeniser2 = new Tokeniser(textLine2);
			bool check2 = tokeniser2->checkFormat(textLine2);

			QVERIFY(check2 == false);
		}
		void testExtractEntryToEdit() {
			string textLine = "edit 4 n hello";
			Tokeniser* tokeniser1 = new Tokeniser(textLine);
			CommonEnum::COMMAND_TYPE command = tokeniser1->getCommand();

			int lineToEdit = tokeniser1->extractLineNum();
			vector<string> newEntry = tokeniser1->extractEntryToEdit();
			string name = newEntry.at(0);

			QVERIFY(name == "hello");
		}

};


//@author A0096723X
class CommonUtilsTest:public QObject {
	Q_OBJECT
private:
	private slots:
		void initTestCase() {
			// Called before all unit tests.

			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");

			qxtLog->addLoggerEngine("file", fileLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);
		}
		void testCompare() {
			Event a("jack",QDate(2014, 1, 23),QTime(14,00),
				QDate(2014, 1, 23),QTime(13,00), 0);
			Event b("jack1",QDate(2014, 1, 23),QTime(14,30),
				QDate(2014, 1, 23),QTime(13,30), 0);
			Event c("jack2",QDate(2014, 1, 23),QTime(14,30),
				QDate(2014, 1, 23),QTime(13,30), 0);
			Task d("T1", QDate(2014, 1, 23), QTime(12,00),0);
			Task e("T2", QDate(2014, 1, 23), QTime(12,00),0);
			//partition of earlier date
			QVERIFY(CommonUtils::greater(&a,&b)==true);//earlier start date first
			//Partition of same date, different name
			QVERIFY(CommonUtils::greater(&c,&b)==false);//alphabetical order
			//Partition of exact equal entries, returns false
			QVERIFY(CommonUtils::greater(&b,&b)==false);
			//Partition of event vs task
			QVERIFY(CommonUtils::greater(&d,&c)==true);//task ends before event starts
			QVERIFY(CommonUtils::greater(&d,&e)==true);//alphabetical order
		}
		void testToLower() {
			QVERIFY(CommonUtils::toLower("Ab12") == "ab12");
		}
};

class EntriesManagerUTest : public QObject{//stubs for FileManager and Entry are used for this test class
	Q_OBJECT;
	EntriesManager& alpha;
public:
	EntriesManagerUTest():alpha(EntriesManager::getInstance(new FileManagerStub())), QObject() {}
private:
	private slots:
		void initTestCase() {
				// Called before all unit tests.

			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");

			qxtLog->addLoggerEngine("file", fileLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);
		}
		void testGetconflict() {
			for(int i=0; i<10; i++) {
				alpha.addCommand(new EntryStub);//push in 10 entrystubs
			}
			Entry* stub = new EntryStub;
			vector<Entry*> temp = alpha.getConflict(stub);//should return a vector size 0; since entrystub returns false everytime
			QVERIFY(temp.size() == 0);
		}
		void testAdd() {
			//EntriesManager alpha;
			Entry* stub;
			alpha.clearCommand();
			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);//1-2
			alpha.addCommand(stub);

			stub = new Event("jack1",QDate(2014,1,23),QTime(14,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-230
			alpha.addCommand(stub);

			stub = new Event("jack2",QDate(2014,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-330
			alpha.addCommand(stub);

			QVERIFY(alpha._entries.currentDisplayIndex==3);//jack2 conflicts with jack1, activeEntries displays jack1 and jack2
			
			stub = new Task("T1", QDate(2014,1,22), QTime(12,00),0);
			alpha.addCommand(stub);

			stub = new Task("T2", QDate(2014,1,27), QTime(18,00),0);
			alpha.addCommand(stub);

			stub = new Task("T3", QDate(2014,1,28), QTime(9,00),0);
			alpha.addCommand(stub);

			stub = new Task("T5", QDate(2014,1,23), QTime(9,00),0);
			alpha.addCommand(stub);

			stub = new Task("T4", QDate(2014,1,29), QTime(9,00),0);
			alpha.addCommand(stub);

			stub = new Task("T4", QDate(2014,1,29), QTime(9,00),0);
			//8 entries, should have 8 entries.
			QVERIFY(alpha._entries.currentDisplayIndex == 8);
		}
		void testDelete() {
			//valid index
			alpha.deleteCommand(1);
			//ensure entry is deleted
			QVERIFY(alpha._entries.currentDisplayIndex==7);

			string output;
			//invalid index
			try{
				alpha.deleteCommand(19);
			}
			catch(BotException e) {
				output = (e.what());
			}
			QVERIFY(output == BotException::STRING_INVALID_INDEX);

			output.clear();
			//invalid index
			try{
				alpha.deleteCommand(0);
			}
			catch(BotException e) {
				output = (e.what());
			}
			QVERIFY(output == BotException::STRING_INVALID_INDEX);
		}
		void testEdit() {
			vector<string> entryVector;
			string testName = "tryout";

			entryVector.push_back(testName);
			for(int i=0; i<4; i++) {
				entryVector.push_back("");
			}//fill to size 5
			alpha.editCommand(1, entryVector);
			
			QVERIFY(alpha._entries.activeEntries[0]->getName() == testName);
		}
		void testSearchUpToDate() {
			alpha.searchDay(QDate(2014,1,23),CommonEnum::SEARCH_TYPE_DEFAULT);
			QVERIFY(alpha._entries.currentDisplayIndex==4);//index is 4
		}
		void testSearchName() {
			alpha.searchCommand("jack2", CommonEnum::SEARCH_TYPE_DEFAULT);
			QVERIFY(alpha._entries.currentDisplayIndex==1);
			
			alpha.displayCommand();
			QVERIFY(alpha._entries.currentDisplayIndex==7);

			alpha.searchCommand("asdasd", CommonEnum::SEARCH_TYPE_DEFAULT);
			QVERIFY(alpha._entries.currentDisplayIndex==0);
		}
		void testSearchAttributes() {
			//Equivalence partitioning for terms within the existing entries
			//terms outside the existing partitions
			alpha.displayCommand();
			alpha.searchCommand("27/1");//only T2 should be displayed
			QVERIFY(alpha._entries.currentDisplayIndex==1);
			alpha.displayCommand();

			alpha.searchCommand("27/1 jack");//jacks and T2 should be displayed
			QVERIFY(alpha._entries.currentDisplayIndex==4);//contains terms within existing entries
			alpha.displayCommand();

			alpha.searchCommand("27/1 jak");//only T2 should be displayed
			QVERIFY(alpha._entries.currentDisplayIndex==1);//contains terms outside existing entries
			alpha.displayCommand();

			QVERIFY(alpha._entries.currentDisplayIndex==7);
			alpha.displayCommand();

			alpha.searchCommand("jack has");//all words searched individually, jacks should be returned
			QVERIFY(alpha._entries.currentDisplayIndex==3);
		}
		void testUndo() {//9 actions so far
			alpha.undoCommand();//at this point index is 3, hence when redo called, is index 3
			QVERIFY(alpha._entries.currentDisplayIndex==7);
			string output;
			try{
				for(int i=0; i<10; i++)
					alpha.undoCommand();
			}
			catch(BotException e) {
				output = e.what();
			}
			QVERIFY(output==BotException::STRING_INVALID_UNDO);
		}
		void testRedo() {
			string output;
			for(int i=0; i<10; i++)
				alpha.redoCommand();
			QVERIFY(alpha._entries.currentDisplayIndex==3);
			try{
				alpha.redoCommand();
			}
			catch(BotException e) {
				output = e.what();
			}
			QVERIFY(output == BotException::STRING_INVALID_REDO);
		}
		void testUndoLimit() {//current displayindex should be 2 here, since last redo. UNDO LIMIT:10
			//undo attempts
			//0. within range (1-9) as demonstrated above
			//1. equal to max attempt = 10
			//2. exceed range >=11
			alpha.clearCommand();//1 action
			for(int i=0; i<9; i++) {//9 actions here
				Entry* stub = new Event();
				alpha.addCommand(stub);
			}//redo stack is emptied
			QVERIFY(alpha._entries.currentDisplayIndex == 9);// 9 items added
			for(int i=0; i<10; i++) {
				alpha.undoCommand();
			}//10 undos
			QVERIFY(alpha._entries.currentDisplayIndex == 3);//undo until clearcommand
			for(int i=0; i<10; i++) {
				alpha.redoCommand();
			}//10 redos
			QVERIFY(alpha._entries.currentDisplayIndex == 9);
			string output;
			try{
				for(int i=0; i<11; i++) {
					alpha.undoCommand();
				}//11 undos, should return invalid exception since only 10 undos allowed
			}
			catch(BotException e) {
				output = e.what();
			}
			QVERIFY(output==BotException::STRING_INVALID_UNDO);
		}
};

class EntriesSorterTest:public QObject {
	Q_OBJECT
private:
	private slots:
		void initTestCase() {
			// Called before all unit tests.

			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");

			qxtLog->addLoggerEngine("file", fileLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);
		}
		void testIsPast() {
			Entry* stub;
			//past events, events happening today, events ending in future

			//Partition past event
			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);//1-2
			QVERIFY(EntriesSorter::isPast(stub));
			delete stub;

			//Partition past event up til today 0000, border case
			stub = new Event("jack",QDate::currentDate(),QTime(00,00),
				QDate(2014,1,23),QTime(13,00), 0);
			QVERIFY(EntriesSorter::isPast(stub));
			delete stub;

			//Partition event not started
			stub = new Event("jack",QDate(2214,12,23),QTime(14,00),
				QDate::currentDate(),QTime(23,59), 0);
			QVERIFY(!EntriesSorter::isPast(stub));
			delete stub;

			//Partition event started, not yet ended
			stub = new Event("jack",QDate(2214,12,23),QTime(14,00),
				QDate(2214,1,23),QTime(13,00), 0);
			QVERIFY(!EntriesSorter::isPast(stub));
			delete stub;
		}
		void testIsToday() {
			Entry* stub;//past events, events happening today, events ending in future

			//Partition ending in past
			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);//1-2
			QVERIFY(!EntriesSorter::isToday(stub));
			delete stub;

			//Partition border starting today 0000
			stub = new Event("jack",QDate::currentDate(),QTime(00,00),
				QDate(2014,1,23),QTime(13,00), 0);
			QVERIFY(EntriesSorter::isToday(stub));
			delete stub;

			//Partition border ended ytd 2359
			stub = new Event("jack",QDate::currentDate().addDays(-1),QTime(23,59),
				QDate(2014,1,23),QTime(13,00), 0);
			QVERIFY(!EntriesSorter::isToday(stub));
			delete stub;

			//Partition border starts today 2359
			stub = new Event("jack",QDate(2214,12,23),QTime(14,00),
				QDate::currentDate(),QTime(23,59), 0);
			QVERIFY(EntriesSorter::isToday(stub));
			delete stub;

			//Partition starts after today
			stub = new Event("jack",QDate(2214,12,23),QTime(14,00),
				QDate(2214,1,23),QTime(13,00), 0);
			QVERIFY(!EntriesSorter::isToday(stub));
			delete stub;
		}
		void testIsTomorrow() {
			Entry* stub;
			//past events, events happening today, events ending in future
			
			//Partition past event
			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);//1-2
			QVERIFY(!EntriesSorter::isTomorrow(stub));
			delete stub;

			//Partition border ending today 2359
			stub = new Event("jack",QDate::currentDate(),QTime(23,59),
				QDate(2014,1,23),QTime(13,00), 0);
			QVERIFY(!EntriesSorter::isTomorrow(stub));//ends today 2359
			delete stub;

			//Partition border ending tomorrow 0000
			stub = new Event("jack",QDate::currentDate().addDays(1),QTime(00,00),
				QDate(2014,1,23),QTime(13,00), 0);
			QVERIFY(EntriesSorter::isTomorrow(stub));//ends tomorrow 0000
			delete stub;

			//Partition ending within tomorrow
			stub = new Event("jack",QDate::currentDate().addDays(1),QTime(23,59),
				QDate(2014,1,23),QTime(13,00), 0);
			QVERIFY(EntriesSorter::isTomorrow(stub));//ends tomorrow 2359
			delete stub;

			//Partition border starting tomorrow and ending in future
			stub = new Event("jack",QDate(2214,12,23),QTime(14,00),
				QDate::currentDate().addDays(1),QTime(23,59), 0);
			QVERIFY(EntriesSorter::isTomorrow(stub));//starts tomorrow 2359 end in future
			delete stub;

			//Partition starts and ends in future
			stub = new Event("jack",QDate(2214,12,23),QTime(14,00),
				QDate(2214,1,23),QTime(13,00), 0);
			QVERIFY(!EntriesSorter::isTomorrow(stub));//starts in future
			delete stub;
		}
		void testIsTask() {
			Entry* stub;
			//past events, events happening today, events ending in future

			//Partition is not task
			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);//1-2
			QVERIFY(!EntriesSorter::isTask(stub));
			delete stub;

			//Partition is task
			stub = new Task("T1", QDate(2014,1,22), QTime(12,00),0);
			QVERIFY(EntriesSorter::isTask(stub));
			delete stub;
		}
		void testDefaultSort() {//only past and future entries tested, due to currentDate used in functions
			vector<Entry*> entries;
			Entry* stub;

			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);
			//1-2
			entries.push_back(stub);

			stub = new Event("jack1",QDate(2014,1,23),QTime(14,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-230
			entries.push_back(stub);

			stub = new Event("jack2",QDate(2014,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-330
			entries.push_back(stub);

			stub = new Event("jack3",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-330
			entries.push_back(stub);
			//jack 3 spans across today, and ends way in future, appears in middle of vector

			stub = new Event("jack4",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-330
			entries.push_back(stub);
			//jack 4 spans across today, and ends way in future, appears in middle of vector

			stub = new Task("T1", QDate(2014,1,22), QTime(12,00),0);
			entries.push_back(stub);

			stub = new Task("T2", QDate(2014,1,27), QTime(18,00),0);
			entries.push_back(stub);

			stub = new Task("T3", QDate(2014,1,28), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T5", QDate(2014,1,29), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T6", QDate(2014,1,23), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T7", QDate(2214,1,29), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T8", QDate(2214,1,23), QTime(9,00),0);
			entries.push_back(stub);

			stub = NULL;
			EntriesSorter::defaultSort(entries);
			QVERIFY(entries[0]->getName() == "T1");
			QVERIFY(entries[1]->getName() == "T6");
			QVERIFY(entries[2]->getName() == "jack");
			QVERIFY(entries[3]->getName() == "jack1");
			QVERIFY(entries[4]->getName() == "jack2");
			QVERIFY(entries[5]->getName() == "T2");
			QVERIFY(entries[6]->getName() == "T3");
			QVERIFY(entries[7]->getName() == "T5");
			QVERIFY(entries[8]->getName() == "jack3");
			QVERIFY(entries[9]->getName() == "jack4");
			QVERIFY(entries[10]->getName() == "T8");
			QVERIFY(entries[11]->getName() == "T7");

			for(int i=0; i<entries.size(); i++) {
				delete entries[i];
				entries[i]=NULL;
			}


		}
		void testSearchSort() {
			//only past and future entries tested, due to currentDate used in functions
			vector<Entry*> entries;
			Entry* stub;

			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);
			//1-2
			entries.push_back(stub);

			stub = new Event("jack1",QDate(2014,1,23),QTime(14,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-230
			entries.push_back(stub);

			stub = new Event("jack2",QDate(2014,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-330
			entries.push_back(stub);

			stub = new Event("jack3",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-330
			entries.push_back(stub);

			stub = new Event("jack4",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-330
			entries.push_back(stub);

			stub = new Task("T1", QDate(2014,1,22), QTime(12,00),0);
			entries.push_back(stub);

			stub = new Task("T2", QDate(2014,1,27), QTime(18,00),0);
			entries.push_back(stub);

			stub = new Task("T3", QDate(2014,1,28), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T5", QDate(2014,1,29), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T6", QDate(2014,1,23), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T7", QDate(2214,1,29), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T8", QDate(2214,1,23), QTime(9,00),0);
			entries.push_back(stub);

			stub = NULL;
			EntriesSorter::sortByDate(entries);
			QVERIFY(entries[0]->getName() == "T1");
			QVERIFY(entries[1]->getName() == "T6");
			QVERIFY(entries[2]->getName() == "jack");
			QVERIFY(entries[3]->getName() == "jack1");
			QVERIFY(entries[4]->getName() == "jack2");
			QVERIFY(entries[5]->getName() == "jack3");
			QVERIFY(entries[6]->getName() == "jack4");
			QVERIFY(entries[7]->getName() == "T2");
			QVERIFY(entries[8]->getName() == "T3");
			QVERIFY(entries[9]->getName() == "T5");
			QVERIFY(entries[10]->getName() == "T8");
			QVERIFY(entries[11]->getName() == "T7");
			for(int i=0; i<entries.size(); i++) {
				delete entries[i];
				entries[i]=NULL;
			}
		}
		void testGetCount() {
			//only past and future entries tested, due to currentDate used in functions
			vector<Entry*> entries;
			Entry* stub;

			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);
			//1-2
			entries.push_back(stub);

			stub = new Event("jack1",QDate(2014,1,23),QTime(14,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-230
			entries.push_back(stub);

			stub = new Event("jack2",QDate(2014,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-330
			entries.push_back(stub);

			stub = new Event("jack3",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-330
			entries.push_back(stub);
			//jack 3 spans across today, and ends way in future, appears in middle of vector

			stub = new Event("jack4",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-330
			entries.push_back(stub);
			//jack 4 spans across today, and ends way in future, appears in middle of vector

			stub = new Task("T1", QDate(2014,1,22), QTime(12,00),0);
			entries.push_back(stub);

			stub = new Task("T2", QDate(2014,1,27), QTime(18,00),0);
			entries.push_back(stub);

			stub = new Task("T3", QDate(2014,1,28), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T5", QDate(2014,1,29), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T6", QDate(2014,1,23), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T7", QDate(2214,1,29), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T8", QDate(2214,1,23), QTime(9,00),0);
			entries.push_back(stub);

			stub = NULL;
			CommonEnum::ReturnCount counter = EntriesSorter::getCount(entries);
			QVERIFY(counter.numOverdue == 8);
			QVERIFY(counter.numToday == 2);
			QVERIFY(counter.numFuture == 2);
			QVERIFY(counter.numTasks == 7);
			QVERIFY(counter.numEvents == 5);
			for(int i=0; i<entries.size(); i++) {
				delete entries[i];
				entries[i]=NULL;
			}
		}
		void testSplitVector() {
			//only past and future entries tested, due to currentDate used in functions
			vector<Entry*> entries;
			Entry* stub;
			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);//1-2
			entries.push_back(stub);

			stub = new Event("jack1",QDate(2014,1,23),QTime(14,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-230
			entries.push_back(stub);

			stub = new Event("jack2",QDate(2014,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 1);//2-330
			entries.push_back(stub);

			stub = new Event("jack3",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-330
			entries.push_back(stub);
			//jack 3 spans across today, and ends way in future, appears in middle of vector

			stub = new Event("jack4",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 1);//2-330
			entries.push_back(stub);
			//jack 4 spans across today, and ends way in future, appears in middle of vector

			stub = new Task("T1", QDate(2014,1,22), QTime(12,00),0);
			entries.push_back(stub);

			stub = new Task("T2", QDate(2014,1,27), QTime(18,00),0);
			entries.push_back(stub);

			stub = new Task("T3", QDate(2014,1,28), QTime(9,00),1);
			entries.push_back(stub);

			stub = new Task("T5", QDate(2014,1,29), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T6", QDate(2014,1,23), QTime(9,00),1);
			entries.push_back(stub);

			stub = new Task("T7", QDate(2214,1,29), QTime(9,00),0);
			entries.push_back(stub);

			stub = new Task("T8", QDate(2214,1,23), QTime(9,00),0);
			entries.push_back(stub);

			stub = NULL;
			vector<Entry*> found;
			vector<Entry*> notFound;
			EntriesSorter::splitVector("jack   t", entries, found, notFound, CommonEnum::SEARCH_TYPE_CUMULATIVE);
			QVERIFY(found.size() == 12);
			EntriesSorter::splitVector("jack   t", entries, found, notFound, CommonEnum::SEARCH_TYPE_DEFAULT);
			QVERIFY(found.size() == 0);
			EntriesSorter::splitVectorTask(entries, found, notFound);
			QVERIFY(found.size() == 7);
			EntriesSorter::splitVectorEvent(entries, found, notFound);
			QVERIFY(found.size() == 5);
			EntriesSorter::splitVectorDay(QDate(2214,1,23), entries, found, notFound, CommonEnum::SEARCH_TYPE_CUMULATIVE);
			QVERIFY(found.size() ==11);
			EntriesSorter::splitVectorDay(QDate(2214,1,23), entries, found, notFound, CommonEnum::SEARCH_TYPE_DEFAULT);
			QVERIFY(found.size() == 3);
			EntriesSorter::splitVectorStatus(0, entries, found, notFound);
			QVERIFY(found.size() == 8);
			EntriesSorter::splitVectorStatus(1, entries, found, notFound);
			QVERIFY(found.size() == 4);
			for(int i=0; i<entries.size(); i++) {
				delete entries[i];
				entries[i]=NULL;
			}
		}

};

class EntriesDisplayTest:public QObject {
	Q_OBJECT
private:
	private slots:
		void initTestCase() {
			// Called before all unit tests.

			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");

			qxtLog->addLoggerEngine("file", fileLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);
		}
		void testDefaultString() {//only past and future entries tested, due to currentDate used in functions
			vector<Entry*> entries;
			vector<Entry*> conflictEntries;
			Entry* stub;
			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);//1-2
			entries.push_back(stub);
			stub = new Event("jack1",QDate(2014,1,23),QTime(14,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-230
			entries.push_back(stub);
			conflictEntries.push_back(stub);
			stub = new Event("jack2",QDate(2014,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-330
			entries.push_back(stub);
			stub = new Event("jack3",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-330
			entries.push_back(stub);//jack 3 spans across today, and ends way in future, appears in middle of vector
			stub = new Event("jack4",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-330
			entries.push_back(stub);//jack 4 spans across today, and ends way in future, appears in middle of vector
			stub = new Task("T1", QDate(2014,1,22), QTime(12,00),0);
			entries.push_back(stub);
			stub = new Task("T2", QDate(2014,1,27), QTime(18,00),0);
			entries.push_back(stub);
			stub = new Task("T3", QDate(2014,1,28), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T5", QDate(2014,1,29), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T6", QDate(2014,1,23), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T7", QDate(2214,1,29), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T8", QDate(2214,1,23), QTime(9,00),0);
			entries.push_back(stub);
			EntriesSorter::defaultSort(entries);
			EntriesDisplay display(stub, conflictEntries);
			vector<vector<CommonEnum::ReturnString>> output = display.getDefaultString(entries);
			stub = NULL;
			QVERIFY(output.size() == 4);
			QVERIFY(output[0].size() == 9);
			QVERIFY(output[1].size() == 3);//today 2 entries
			QVERIFY(output[2].size() == 2);//tommorrow no entries
			QVERIFY(output[3].size() == 3);
			QVERIFY(output[3][1].format==CommonEnum::DISPLAY_FORMAT_NEW);
			QVERIFY(output[0][4].format==CommonEnum::DISPLAY_FORMAT_CLASH);
			for(int i=0; i<entries.size(); i++) {
				delete entries[i];
				entries[i]=NULL;
			}
		}
		void testSearchString() {//only past and future entries tested, due to currentDate used in functions
			vector<Entry*> entries;
			vector<Entry*> conflictEntries;
			Entry* stub;
			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);//1-2
			entries.push_back(stub);
			stub = new Event("jack1",QDate(2014,1,23),QTime(14,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-230
			entries.push_back(stub);
			conflictEntries.push_back(stub);
			stub = new Event("jack2",QDate(2014,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-330
			entries.push_back(stub);
			stub = new Event("jack3",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-330
			entries.push_back(stub);//jack 3 spans across today, and ends way in future, appears in middle of vector
			stub = new Event("jack4",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-330
			entries.push_back(stub);//jack 4 spans across today, and ends way in future, appears in middle of vector
			stub = new Task("T1", QDate(2014,1,22), QTime(12,00),0);
			entries.push_back(stub);
			stub = new Task("T2", QDate(2014,1,27), QTime(18,00),0);
			entries.push_back(stub);
			stub = new Task("T3", QDate(2014,1,28), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T5", QDate(2014,1,29), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T6", QDate(2014,1,23), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T7", QDate(2214,1,29), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T8", QDate(2214,1,23), QTime(9,00),0);
			entries.push_back(stub);
			EntriesSorter::sortByDate(entries);
			string searchLabel = "testSearch";
			EntriesDisplay display(stub, conflictEntries);
			vector<vector<CommonEnum::ReturnString>> output = display.getSearchString(entries, searchLabel);
			stub = NULL;
			QVERIFY(output.size() == 1);
			QVERIFY(output[0].size() == 13);
			QVERIFY(output[0][0].entry.first=="Search testSearch:");//today 2 entries
			QVERIFY(output[0][11].format==CommonEnum::DISPLAY_FORMAT_NEW);
			QVERIFY(output[0][4].format==CommonEnum::DISPLAY_FORMAT_CLASH);
			for(int i=0; i<entries.size(); i++) {
				delete entries[i];
				entries[i]=NULL;
			}
		}
		void testSearchDateString() {//only past and future entries tested, due to currentDate used in functions
			vector<Entry*> entries;
			vector<Entry*> conflictEntries;
			Entry* stub;
			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);//1-2
			entries.push_back(stub);
			stub = new Event("jack1",QDate(2014,1,23),QTime(14,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-230
			entries.push_back(stub);
			conflictEntries.push_back(stub);
			stub = new Event("jack2",QDate(2014,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-330
			entries.push_back(stub);
			stub = new Event("jack3",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-330
			entries.push_back(stub);//jack 3 spans across today, and ends way in future, appears in middle of vector
			stub = new Event("jack4",QDate(2214,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);//2-330
			entries.push_back(stub);//jack 4 spans across today, and ends way in future, appears in middle of vector
			stub = new Task("T1", QDate(2014,1,22), QTime(12,00),0);
			entries.push_back(stub);
			stub = new Task("T2", QDate(2014,1,27), QTime(18,00),0);
			entries.push_back(stub);
			stub = new Task("T3", QDate(2014,1,28), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T5", QDate(2014,1,29), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T6", QDate(2014,1,23), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T7", QDate(2214,1,29), QTime(9,00),0);
			entries.push_back(stub);
			stub = new Task("T8", QDate(2214,1,23), QTime(9,00),0);
			entries.push_back(stub);
			//stub = NULL;
			EntriesSorter::sortByDate(entries);
			string searchLabel = "Wednesday, 23 Apr";
			EntriesDisplay display(stub, conflictEntries);
			vector<vector<CommonEnum::ReturnString>> output = display.getSearchDateString(entries, searchLabel);
			QVERIFY(output.size() == 1);
			QVERIFY(output[0].size() == 13);
			QVERIFY(output[0][0].entry.first=="Date Searched:");//today 2 entries
			QVERIFY(output[0][11].format==CommonEnum::DISPLAY_FORMAT_NEW);
			QVERIFY(output[0][4].format==CommonEnum::DISPLAY_FORMAT_CLASH);
			for(int i=0; i<entries.size(); i++) {
				delete entries[i];
				entries[i]=NULL;
			}
		}

};
//Integrated testing of EntriesManager with FileManager
class EntriesManagerITest:public QObject {//tests here involve the actual FileManager and Events/Tasks classes
	Q_OBJECT
public:
	EntriesManagerITest():alpha(EntriesManager::getInstance(new FileManagerStub())),  QObject() {}
private:
	EntriesManager& alpha;
	private slots:
		void initTestCase() {
			// Called before all unit tests.

			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");

			qxtLog->addLoggerEngine("file", fileLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);
		}
		
		void testAdd() {
			Entry* stub;
			alpha.clearCommand();
			stub = new Event("jack",QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);
			//1-2
			alpha.addCommand(stub);

			stub = new Event("jack1",QDate(2014,1,23),QTime(14,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-230
			alpha.addCommand(stub);

			stub = new Event("jack2",QDate(2014,1,23),QTime(15,30),
				QDate(2014,1,23),QTime(14,00), 0);
			//2-330
			alpha.addCommand(stub);
			//jack2 conflicts with jack1, activeEntries displays jack1 and jack2

			stub = new Task("T1", QDate(2014,1,22), QTime(12,00),0);
			alpha.addCommand(stub);

			stub = new Task("T2", QDate(2014,1,27), QTime(18,00),0);
			alpha.addCommand(stub);

			stub = new Task("T3", QDate(2014,1,28), QTime(9,00),0);
			alpha.addCommand(stub);

			stub = new Task("T5", QDate(2014,1,29), QTime(9,00),0);
			alpha.addCommand(stub);

			stub = new Task("T4", QDate(2014,1,23), QTime(9,00),0);
			alpha.addCommand(stub);

			QVERIFY(alpha._entries.currentDisplayIndex==8);
		}
		void testDelete() {

			alpha.deleteCommand(1);
			//T1 is on top after sorting.. T1 deleted

			QVERIFY(alpha._entries.currentDisplayIndex==7);
			string output;
			try{
				alpha.deleteCommand(19);
			}//invalid index
			catch(BotException e) {
				output = (e.what());
			}
			QVERIFY(output == BotException::STRING_INVALID_INDEX);
			output.clear();
			try{
				alpha.deleteCommand(0);
			}//invalid index
			catch(BotException e) {
				output = (e.what());
			}
			QVERIFY(output == BotException::STRING_INVALID_INDEX);
		}
		void testSearchUpToDate() {
			alpha.searchDay(QDate(2014,1,23),CommonEnum::SEARCH_TYPE_DEFAULT);
			QVERIFY(alpha._entries.currentDisplayIndex==4);//index is 4
		}
		void testSearchName() {
			alpha.searchCommand("jack2", CommonEnum::SEARCH_TYPE_DEFAULT);
			QVERIFY(alpha._entries.currentDisplayIndex==1);

			alpha.displayCommand();
			QVERIFY(alpha._entries.currentDisplayIndex==7);

			alpha.searchCommand("asdasd", CommonEnum::SEARCH_TYPE_DEFAULT);
			QVERIFY(alpha._entries.currentDisplayIndex==0);
			//none found
		}
		void testSearchAttributes() {
			alpha.displayCommand();
			alpha.searchCommand("27/1");//only T2 should be displayed
			QVERIFY(alpha._entries.currentDisplayIndex==1);
			alpha.displayCommand();
			QVERIFY(alpha._entries.currentDisplayIndex==7);
			alpha.displayCommand();
			alpha.searchCommand("jack");//all words searched individually, jacks should be returned
			QVERIFY(alpha._entries.currentDisplayIndex==3);
		}
		void testUndo() {
			//9 actions so far
			
			alpha.undoCommand();
			//at this point index is 3, hence when redo called, is index 3
			
			QVERIFY(alpha._entries.currentDisplayIndex==8);
			string output;
			try{
				for(int i=0; i<10; i++)
					alpha.undoCommand();
			}
			catch(BotException e) {
				output = e.what();
			}
			QVERIFY(output==BotException::STRING_INVALID_UNDO);
		}
		void testRedo() {
			string output;
			
			for(int i=0; i<10; i++)
				alpha.redoCommand();
			QVERIFY(alpha._entries.currentDisplayIndex==3);
			
			try{
				alpha.redoCommand();
			}
			catch(BotException e) {
				output = e.what();
			}
			
			QVERIFY(output == BotException::STRING_INVALID_REDO);
		}
		void testgetConflict() {
			//new events are either
			//1. lie across and exceed range of multiple old events
			//2. out of range of old event ranges
			//3. lie within range of one single event
			//4. lie within range of multiple old events
			//5. lie in exact same range of 1 old event
			//6. lie in exact same range of more than 1 old event
			alpha.displayCommand();
			QVERIFY(alpha._entries.currentDisplayIndex==7);
			Entry* stub = new Event("Conflict", QDate(2014,1,23),QTime(16,30),
				QDate(2014,1,23),QTime(12,00), 0);
			//12-430, should clash with 1-2, 2-230, 2-330

			vector<Entry*> temp = alpha.getConflict(stub);
			//new range encompasses old ranges, 

			QVERIFY(temp.size()==3);
			delete stub;

			stub = new Event("Conflict", QDate(2014,1,23),QTime(13,00),
				QDate(2014,1,23),QTime(12,00), 0);
			//12-1300, should not clash
			temp = alpha.getConflict(stub);
			//out of range before

			QVERIFY(temp.size()==0);
			delete stub;

			stub = new Event("Conflict", QDate(2014,1,23),QTime(16,00),
				QDate(2014,1,23),QTime(13,30), 0);
			//1330-1600, should clash with 1-2, 2-230
			temp = alpha.getConflict(stub);
			
			//new range is between range of two old ranges
			QVERIFY(temp.size()==3);
			delete stub;

			stub = new Event("Conflict", QDate(2014,1,23),QTime(14,00),
				QDate(2014,1,23),QTime(13,00), 0);
			//1300-1400, should clash with 1-2

			temp = alpha.getConflict(stub);//exact conflict
			QVERIFY(temp.size()==1);
			delete stub;

			stub = new Event("Conflict", QDate(2014,1,23),QTime(14,30),
				QDate(2014,1,23),QTime(13,00), 0);
			//1300-1530, should clash with 1-2, 2-230, 3-330

			temp = alpha.getConflict(stub);
			//exact clash with two old ranges
			
			QVERIFY(temp.size()==3);
			delete stub;
			stub = new Event("Conflict", QDate(2014,1,23),QTime(16,00),
				QDate(2014,1,23),QTime(15,30), 0);
			//1530-1600, should clash with none

			temp = alpha.getConflict(stub);
			//out of range after

			QVERIFY(temp.size()==0);
		}

		void testUndoLimit() {//current displayindex should be 2 here, since last redo. UNDO LIMIT:10
			//undo attempts
			//0. within range (1-9) as demonstrated above
			//1. equal to max attempt = 10
			//2. exceed range >=11
			alpha.clearCommand();//1 action
			for(int i=0; i<9; i++) {
				//9 actions here
				Entry* stub = new Event();
				alpha.addCommand(stub);
			}
			//redo stack is emptied

			QVERIFY(alpha._entries.currentDisplayIndex == 9);
			
			// 9 items added

			for(int i=0; i<10; i++) {
				alpha.undoCommand();
			}
			//10 undos
			QVERIFY(alpha._entries.currentDisplayIndex == 7);
			//undo until clearcommand, beforewhich had 7 index

			for(int i=0; i<10; i++) {
				alpha.redoCommand();
			}
			//10 redos

			QVERIFY(alpha._entries.currentDisplayIndex == 9);

			string output;
			try{
				for(int i=0; i<11; i++) {
					alpha.undoCommand();
				}//11 undos, should return invalid exception since only 10 undos allowed
			}
			catch(BotException e) {
				output = e.what();
			}
			QVERIFY(output==BotException::STRING_INVALID_UNDO);
		}
};

//@author A0101038Y

class FileManagerTest : public QObject {
	Q_OBJECT
private:
	private slots:
		void initTestCase() {
			// Called before all unit tests.

			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");
			QxtLoggerEngine *stdoutLogger = new QxtBasicSTDLoggerEngine();

			qxtLog->addLoggerEngine("file", fileLogger);
			qxtLog->addLoggerEngine("stdout", stdoutLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);
			qxtLog->enableLogLevels("stdout", QxtLogger::AllLevels);
		}
		void testCompare() {
			//testing how the entries are sorted
			Event a("jack",QDate(2014, 1, 23),QTime(14,00),
				QDate(2014, 1, 23),QTime(13,00), 0);
			Event b("jack1",QDate(2014, 1, 23),QTime(14,30),
				QDate(2014, 1, 23),QTime(13,30), 0);
			Event c("jack2",QDate(2014, 1, 23),QTime(14,00),
				QDate(2014, 1, 23),QTime(14,00), 0);
			QVERIFY(CommonUtils::greater(&a,&b)==true);//earlier date first
			QVERIFY(CommonUtils::greater(&c,&a)==false);//alphabetical order
		}
		void testFileManager1() {
			//testing the way the storage file is managed
			FileManager& file= FileManager::getInstance("ii.txt");
			vector<Entry*> alpha;
			Event a("jack",QDate(2014, 1, 23),QTime(14,00),
				QDate(2014, 1, 23),QTime(13,00), 0);
			Event b("jack1",QDate(2014, 1, 23),QTime(14,30),
				QDate(2014, 1, 23),QTime(13,30), 0);
			Event c("jack2",QDate(2014, 1, 23),QTime(14,30),
				QDate(2014, 1, 23),QTime(14,00), 0);
			Task ta("T1", QDate(2014,1,23), QTime(14,00), 0);
			Task tb("T2", QDate(2014,1,24), QTime(15,00),0);
			Task tc("T3", QDate(2014,1,25), QTime(16,00),0);
			alpha.push_back(&a);
			alpha.push_back(&b);
			alpha.push_back(&c);
			alpha.push_back(&ta);
			alpha.push_back(&tb);
			alpha.push_back(&tc);
			file.updateFromVector(alpha);

			vector<Entry*> beta = file.getEntries();
			QVERIFY(alpha.size()==beta.size());
			for(int i=0; i< alpha.size(); i++) {
				QVERIFY(beta[i]->toString() == alpha[i]->toString());
			}
			FileManager& file1= FileManager::getInstance("il.txt");
			file1.updateFromVector(beta);

			vector<Entry*> gamma = file1.getEntries();
			QVERIFY(beta.size() == gamma.size());
		}
		void testFileManager2() {
			//testing the way the storage file is maintained
			FileManager& file3= FileManager::getInstance("aa.txt");
			vector<Entry*> gamma;
			Event a("jack",QDate(2014, 1, 23),QTime(14,00),
				QDate(2014, 1, 23),QTime(13,00), 0);
			Event b("jack1",QDate(2014, 1, 23),QTime(14,30),
				QDate(2014, 1, 23),QTime(13,30), 0);
			Event c("jack2",QDate(2014, 1, 23),QTime(14,30),
				QDate(2014, 1, 23),QTime(14,00), 0);
			Task ta("T1", QDate(2014,1,23), QTime(14,00), 0);
			Task tb("T2", QDate(2014,1,24), QTime(15,00),0);
			Task tc("T3", QDate(2014,1,25), QTime(16,00),0);
			gamma.push_back(&a);
			gamma.push_back(&b);
			gamma.push_back(&c);
			gamma.push_back(&ta);
			gamma.push_back(&tb);
			gamma.push_back(&tc);
			file3.updateFromVector(gamma);
			vector<Entry*> delta = file3.getEntries();
			QVERIFY(delta.size()==gamma.size());
			for(int i=0; i< gamma.size(); i++) {
				QVERIFY(delta[i]->toString() == gamma[i]->toString());
			}
			Task ua("T4", QDate(2014,1,26), QTime(14,00), 0);
			Task ub("T5", QDate(2014,1,27), QTime(15,00),0);
			Task uc("T6", QDate(2014,1,28), QTime(16,00),0);
			gamma.push_back(&ua);
			gamma.push_back(&ub);
			gamma.push_back(&uc);
			file3.updateFromVector(gamma);
			vector<Entry*> sigma = file3.getEntries();
			QVERIFY(sigma.size()==gamma.size());
			for(int i=0; i< gamma.size(); i++) {
				QVERIFY(sigma[i]->toString() == gamma[i]->toString());
			}
			FileManager& file4= FileManager::getInstance("bb.txt");
			file4.updateFromVector(sigma);
		}
		void testUpdateFile() {
			//testing the way file is updated
			FileManager& file10= FileManager::getInstance("babu.txt");
			vector<Entry*> jum = file10.getEntries();
			file10.updateFromVector(jum);
			vector<Entry*> inem = file10.getEntries();
			QVERIFY(jum.size()==inem.size());
		}/*
		void testToString() {
			//test converting an entry to a string for storage
			Entry* alpha;
			alpha = new Event("jack",QDate(2014, 1, 23),QTime(14,00),
				QDate(2014, 1, 23),QTime(13,00), 0);
			cout << alpha->toString();
			delete alpha;
			alpha = new Task("T1", QDate(2014,1,23), QTime(14,00),0);
			cout << alpha->toString();
		}*/
		// Unit Test END
};
class EntryTest:public QObject {
	Q_OBJECT
private:
	private slots:
		void initTestCase() {
			// Called before all unit tests.
			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");
			QxtLoggerEngine *stdoutLogger = new QxtBasicSTDLoggerEngine();

			qxtLog->addLoggerEngine("file", fileLogger);
			qxtLog->addLoggerEngine("stdout", stdoutLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);
			qxtLog->enableLogLevels("stdout", QxtLogger::AllLevels);
		}
		void testDateTime() {
			cout << (QDateTime(QDate::currentDate(), QTime()).isValid()) << endl;
		}
		void testGetStartDate1(){
			QDate StartDate(2014, 4, 1);
			QVERIFY(StartDate.isValid());
		}
//@author A0101038Y
		void testGetStartDate2(){
			//test how to get a start date
			QDate StartDate(2014, 4, 1);
			QVERIFY(StartDate == QDate(2014,4,1));
		}
		void testGetStartTime1(){
			//test how to get a start time
			QTime StartTime(12, 30);
			QVERIFY(StartTime.isValid());
		}
		void testGetStartTime2(){
			//test how to get a start time in a different format
			QTime StartTime (12, 30);
			QVERIFY(StartTime == QTime::fromString("12:30", "hh:mm"));
		}
		void testGetName(){
			//test how to retrieve the name of the entry
			Entry* stub;
			stub = new Event("Jane",QDate(2014,12,1),QTime(14,00),
			QDate(2014,1,1),QTime(12,00), 0);
			string name = stub->getName();
			QVERIFY(name == "Jane");
		}
		void testIsSpanning(){
			//test whether an event is spanning - true case
			Entry* stub;
			stub = new Event("Jennifer",QDate(2014,12,1),QTime(14,00),
			QDate(2014,1,1),QTime(12,00), 0);
			QVERIFY(stub->isSpanning() == true);
		}
		void testIsSpanning2(){
			//test whether an event is spanning - false case
			Entry* stub;
			stub = new Event("Joy",QDate(2014,5,2),QTime(14,00),
			QDate(2014,5,2),QTime(12,00), 0);
			QVERIFY(stub->isSpanning() == false);
		}
		void testIsFloat(){
			//test whether an event is a floating event - true case
			Entry* stub;
			stub = new Event("Jean",QDate::fromString("01132014","ddMMyyyy"),QTime::fromString("2500","hhmm"),
			QDate::fromString("01002014","ddMMyyyy"),QTime::fromString("2500","hhmm"), 0); //invalid dates to mimic NULL
			QVERIFY(stub->isFloat() == true);
		}
		void testIsFloat2(){
			//test whether an event is a floating event - false case
			QDate current = QDate::currentDate();
			Entry* stub;
			//QDate current = QDate(2014,4,1);
			stub = new Event("Joyce",QDate(2014,5,2),QTime(10,00),
			QDate(2014,5,2),QTime(8,00), 0);
			QVERIFY(stub->isFloat() == false);
		}
		void testIsOccuring1(){
			//test whether an event is currently occuring - true case
			QDate current = QDate::currentDate();
			Entry* stub;
			//QDate current = QDate(2014,4,1);
			stub = new Event("Jane",QDate(2014,12,1),QTime(14,00),
			QDate(2014,1,1),QTime(12,00), 0);
			QString curStr = current.toString();
			QDate startStr = stub->getStartDate();
			QString strStr = startStr.toString();
			//cout << curStr.toUtf8().constData() << endl << strStr.toUtf8().constData() << endl;
			//QVERIFY(current == startStr);
			QVERIFY(stub->isOccuring(current) == true);
		}
		void testIsOccuring2(){
			//test whether an event is currently occuring - false case (past)
			QDate current = QDate::currentDate();
			Entry* stub;
			//QDate current = QDate(2014,4,1);
			stub = new Event("Jane",QDate(2014,1,1),QTime(14,00),
			QDate::fromString("01022014","ddMMyyyy"),QTime(12,00), 0);
			QVERIFY(stub->isOccuring(current) == false);
		}
		void testIsPast1(){
			//test whether an event is past event - true case
			Entry* stub;
			QDateTime target = QDateTime::currentDateTime();
			stub = new Event("John",QDate(2014,1,1),QTime(14,00),
			QDate(2014,1,1),QTime(12,00), 0);
			QVERIFY(stub->isPast(target) == true);
		}
		void testIsPast2(){
			//test whether an event is past event - false case
			Entry* stub;
			QDateTime target = QDateTime::currentDateTime();
			stub = new Event("Johnny",QDate::fromString("02012020","ddMMyyyy"),QTime(14,00),
			QDate(2014,1,1),QTime(12,00), 0);
			QVERIFY(stub->isPast(target) == false);
		}
		void testIsPast3(){
			//test whether an event is a past case - false case
			Entry* stub;
			QDateTime target = QDateTime::currentDateTime();
			stub = new Event("Jon",QDate::fromString("05122100","ddMMyyyy"),QTime(14,00),
			QDate::fromString("04122100","ddMMyyyy"),QTime(12,00), 0);
			QVERIFY(stub->isPast(target) == false);
		}
		void testDateValidity(){
			//testing date validity (for edit)
			Entry* stub;
			QDateTime target = QDateTime::currentDateTime();
			stub = new Event("Gina",QDate::fromString("05122100","ddMMyyyy"),QTime(14,00),
			QDate::fromString("04122000","ddMMyyyy"),QTime(12,00), 0);
			QDate startDate = stub->getStartDate();
			QTime startTime = stub->getStartTime();
			QDate endDate = stub->getEndDate();
			QTime endTime = stub->getEndTime();
			QDateTime startDateTime (startDate, startTime);
			QDateTime endDateTime (endDate, endTime);
			QVERIFY(stub->isStartEndDateTimeValid(startDateTime, endDateTime) == true); //time and date are all valid
		}
		void testDateValidity2(){
			//test the validity of the date and time
			Entry* stub;
			stub = new Event("George",QDate::fromString("04122000","ddMMyyyy"),QTime(14,00),
			QDate::fromString("04122000","ddMMyyyy"),QTime(13,59), 0);
			QDateTime target = QDateTime::currentDateTime();
			QDate startDate = stub->getStartDate();
			QTime startTime = stub->getStartTime();
			QDate endDate = stub->getEndDate();
			QTime endTime = stub->getEndTime();
			QDateTime startDateTime (startDate, startTime);
			QDateTime endDateTime (endDate, endTime);
			QVERIFY(stub->isStartEndDateTimeValid(startDateTime, endDateTime) == true); //start time is earlier than end time, true case
		}
		void testDateValidity3(){
			//test the validity of the date and time.
			Entry* stub = new Entry();
			QDate startDate (2014, 4, 1);
			QTime startTime (00, 00);
			QDate endDate (2014, 3, 1);
			QTime endTime (00, 00);
			QDateTime startDateTime (startDate, startTime);
			QDateTime endDateTime (endDate, endTime);
			//cout << startDateTime.toString().toUtf8().constData() << endl << endDateTime.toString().toUtf8().constData() << endl;
			QVERIFY(stub->isStartEndDateTimeValid(startDateTime, endDateTime) == false); //test false becauase end date is earlier than start date
		}
};
//@author A0101038Y
class EventTest:public QObject {
	Q_OBJECT
private:
	private slots:
		void initTestCase() {
			// Called before all unit tests.
			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");
			QxtLoggerEngine *stdoutLogger = new QxtBasicSTDLoggerEngine();

			qxtLog->addLoggerEngine("file", fileLogger);
			qxtLog->addLoggerEngine("stdout", stdoutLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);
			qxtLog->enableLogLevels("stdout", QxtLogger::AllLevels);
		}

		void testOngoingOrNot() { //ongoing case
			Event* stub;
			stub = new Event("Jill",QDate::fromString("23032100","ddMMyyyy"),QTime(14,00),
			QDate::fromString("30032014","ddMMyyyy"),QTime(13,00), 0);
			QVERIFY(stub->isOngoingOrNot() == true );
		}

		void testOngoingOrNot2() { //not ongoing case ()
			Event* stub;
			stub =  new Event("Julia",QDate::fromString("23022014","ddMMyyyy"),QTime(14,00),
			QDate::fromString("30022014","ddMMyyyy"),QTime(13,00), 0);
			QVERIFY(stub->isOngoingOrNot() == false);
		}
		void testOngoingOrNot3(){ //not ongoing border case (past event)
			Event* stub;
			stub =  new Event("Jane",QDate::fromString("28032014","ddMMyyyy"),QTime(14,00),
			QDate::fromString("27032014","ddMMyyyy"),QTime(12,00), 0);
			QVERIFY(stub->isOngoingOrNot() == false);
		}
		void testOngoingOrNot4(){ //not ongoing border case (future event)
			Event* stub;
			stub =  new Event("July",QDate::fromString("28032014","ddMMyyyy"),QTime(13,00),
			QDate::fromString("28032014","ddMMyyyy"),QTime(15,00), 0);
			QVERIFY(stub->isOngoingOrNot() == false);
		}
		void testOngoingOrNot5(){ //not ongoing border case (with invalid dates)
			Event* stub;
			stub =  new Event("Jenny",QDate::fromString("30022014","ddMMyyyy"),QTime(13,00),
			QDate::fromString("31042014","ddMMyyyy"),QTime(15,00), 0);
			QVERIFY(stub->isOngoingOrNot() == false);
		}
		void testOngoingOrNot6(){ //not ongoing border case (with invalid time)
			Event* stub;
			stub =  new Event("Jenny",QDate::fromString("28022014","ddMMyyyy"),QTime::fromString("2500","hhmm"),
			QDate::fromString("30042014","ddMMyyyy"),QTime::fromString("1560","hhmm"), 0);
			QVERIFY(stub->isOngoingOrNot() == false);
		}

		void testgetStatusString1(){ //valid case for Not Done
			Entry* stub;
			stub =  new Event("July",QDate::fromString("28032014","ddMMyyyy"),QTime(13,00),
			QDate::fromString("28032014","ddMMyyyy"),QTime(15,00), 0);
			QVERIFY(stub->getStatusString() == "Not Done");
		}

		void testGetStatusString2() { //valid case for Done
			Entry* stub;
			stub = new Event("Jill",QDate::fromString("23022014","ddMMyyyy"),QTime(14,00),
			QDate::fromString("25022014","ddMMyyyy"),QTime(13,00), 1);
			QVERIFY(stub->getStatusString() == "Done");
		}
};
class BotITest: public QObject {
	Q_OBJECT;
	BotLogic& beta;
public:
	BotITest():beta(BotLogic::getInstance()), QObject() {}
private:
	private slots:
		void initTestCase() {
			// Called before all unit tests.

			// Initialize the logging engines
			QxtLoggerEngine *fileLogger = new QxtBasicFileLoggerEngine("test.log");

			qxtLog->addLoggerEngine("file", fileLogger);

			qxtLog->disableAllLogLevels();

			qxtLog->enableLogLevels("file", QxtLogger::AllLevels);

			beta.executeCommand(CommonUtils::STRING_COMMAND_CLEAR);
		}
		void testAdd() {
			CommonEnum::ReturnStatus output = beta.executeCommand("add alpha");//should be shown in today
			QVERIFY(output.displayMsg[0][0].entry.first == CommonUtils::STRING_HEADER_TODAY);
			QVERIFY(output.displayMsg[0][0].entry.second == QDate::currentDate().toString(CommonUtils::FORMAT_DATE_HEADER).toStdString());
			QVERIFY(output.displayMsg[0][0].format == CommonEnum::DISPLAY_FORMAT_TODAY);
			QVERIFY(output.displayMsg[0][1].entry.first == "1. alpha");
			QVERIFY(output.displayMsg[0][1].entry.second == "");
			QVERIFY(output.displayMsg[0][1].format ==CommonEnum::DISPLAY_FORMAT_NEW);
			QVERIFY(output.displayMsg[1][0].entry.first == CommonUtils::STRING_HEADER_TOMORROW);
			QVERIFY(output.displayMsg[1][0].entry.second == QDate::currentDate().addDays(1).toString(CommonUtils::FORMAT_DATE_HEADER).toStdString());
			QVERIFY(output.displayMsg[1][0].format == CommonEnum::DISPLAY_FORMAT_DEFAULT);
		}
//@author A0101038Y
		void testAdd2() {
			
			CommonEnum::ReturnStatus output = beta.executeCommand("add beta");//should be shown in today
			CommonEnum::ReturnStatus aoutput = beta.executeCommand("add gamma");//should be shown in today as well.
			/*cout<<output.displayMsg[0][0].entry.first<<endl;
			cout<<output.displayMsg[0][0].entry.second<<endl;
			cout<<output.displayMsg[0][0].format<<endl;
			cout<< output.displayMsg[0][1].entry.first << endl;
			cout<< output.displayMsg[0][1].entry.second <<endl;
			cout<< output.displayMsg[0][1].format << endl;
			cout<<output.displayMsg[0][2].entry.first << endl;
			cout<<output.displayMsg[0][2].entry.second<< endl;
			cout<<output.displayMsg[0][2].format<<endl;
			cout<<aoutput.displayMsg[0][3].entry.first << endl;
			cout<<aoutput.displayMsg[0][3].entry.second<< endl;
			cout<<aoutput.displayMsg[0][3].format<<endl;
			cout<<output.displayMsg[1][0].entry.first<<endl;
			cout<<output.displayMsg[1][0].entry.second<<endl;
			cout<<output.displayMsg[1][0].format<<endl;*/
			QVERIFY(output.displayMsg[0][1].entry.first == "1. alpha");
			QVERIFY(output.displayMsg[0][2].entry.first =="2. beta");
			QVERIFY(aoutput.displayMsg[0][3].entry.first =="3. gamma");
		}
		void testDelete1(){

			CommonEnum::ReturnStatus output = beta.executeCommand("delete 1"); //delete alpha
			CommonEnum::ReturnStatus aoutput = beta.executeCommand("delete 1");//delete beta
			QVERIFY(aoutput.displayMsg[0][1].entry.first == "1. gamma");	
		}
		void testDelete2(){

			CommonEnum::ReturnStatus output = beta.executeCommand("add delta");
			CommonEnum::ReturnStatus aoutput = beta.executeCommand ("add tetha");
			CommonEnum::ReturnStatus boutput = beta.executeCommand("delete 1"); //delete delta
			/*cout<<boutput.displayMsg[0][1].entry.first << endl;
			cout<<boutput.displayMsg[0][2].entry.first << endl;*/
			QVERIFY(boutput.displayMsg[0][1].entry.first == "1. gamma");
			QVERIFY(boutput.displayMsg[0][2].entry.first == "2. tetha");	
		}
		void testUndo(){
			CommonEnum::ReturnStatus output = beta.executeCommand("undo");//undo delete delta 
			CommonEnum::ReturnStatus aoutput = beta.executeCommand("undo");//undo add tetha
			CommonEnum::ReturnStatus boutput = beta.executeCommand("undo");//undo add delta
			CommonEnum::ReturnStatus cutput = beta.executeCommand("undo");//undo delete alpha
			CommonEnum::ReturnStatus doutput = beta.executeCommand("undo");//undo delete beta
			/*cout<<doutput.displayMsg[0][1].entry.first <<endl;
			cout<<doutput.displayMsg[0][2].entry.first <<endl;
			cout<<doutput.displayMsg[0][3].entry.first <<endl;*/
			QVERIFY(doutput.displayMsg[0][1].entry.first == "1. alpha");
			QVERIFY(doutput.displayMsg[0][2].entry.first == "2. beta");
			QVERIFY(doutput.displayMsg[0][3].entry.first == "3. gamma");
		}
		void testRedo(){
			CommonEnum::ReturnStatus output = beta.executeCommand("redo"); //redo delete beta
			CommonEnum::ReturnStatus boutput = beta.executeCommand("redo"); //redo delete alpha
			CommonEnum::ReturnStatus coutput = beta.executeCommand("redo"); //redo add delta
			CommonEnum::ReturnStatus doutput = beta.executeCommand("redo"); //redo add tetha
			QVERIFY(doutput.displayMsg[0][1].entry.first == "1. delta" && doutput.displayMsg[0][2].entry.first == "2. gamma" && doutput.displayMsg[0][3].entry.first == "3. tetha");
		}
};

int main(int argc, char** argv)
{
   int status = 0;
   {
	   CommonUtilsTest tc;
      status |= QTest::qExec(&tc, argc, argv);
   }
   {
      EntriesManagerUTest tc;
      status |= QTest::qExec(&tc);
   }
   {
	   EntriesSorterTest tc;
      status |= QTest::qExec(&tc);
   }
  
   {
	   EntriesDisplayTest tc;
      status |= QTest::qExec(&tc, argc, argv);
   }
   {
      EntriesManagerITest tc;
      status |= QTest::qExec(&tc, argc, argv);
   }
      {
      BotITest tc;
      status |= QTest::qExec(&tc, argc, argv);
   }
   {
      FileManagerTest tc;
      status |= QTest::qExec(&tc, argc, argv);
   }
   {
      EntryTest tc;
      status |= QTest::qExec(&tc, argc, argv);
   }
   {
      EventTest tc;
      status |= QTest::qExec(&tc, argc, argv);
   }
   {
	   OutputManagerTest tc;
	   status |= QTest::qExec(&tc, argc, argv);
   }
   {
	   TokeniserTest tc;
	   status |= QTest::qExec(&tc, argc, argv);
   }
   {
	   QApplication a(argc, argv);
	   GUILineEditTest tc;
	   status |= QTest::qExec(&tc, argc, argv);
   }
   cout << status << endl;
   system("pause");
   return status;
}

//QTEST_MAIN(GUILineEditTest);
//QTEST_MAIN(OutputManagerTest);
//QTEST_MAIN(CommonUtilsTest);
//QTEST_MAIN(EntriesSorterTest);
//QTEST_MAIN(EntriesDisplayTest);
//QTEST_MAIN(EntriesManagerUTest);
//QTEST_MAIN(BotITest);
//QTEST_MAIN(EntriesManagerTest);
//QTEST_MAIN(FileManagerTest);
//QTEST_MAIN(EntryTest);
//QTEST_MAIN(TokeniserTest);
#include "main.moc"